home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
game
/
role
/
Ang261Lib.lha
/
src
/
desc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-22
|
21KB
|
828 lines
/*
* desc.c: handle object descriptions, mostly string handling code
*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
* This software may be copied and distributed for educational, research, and
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
#include "constant.h"
#include "config.h"
#include "types.h"
#include "externs.h"
#ifdef USG
#ifndef ATARIST_MWC
#include <string.h>
#endif
#else
#include <strings.h>
#endif
/* Lets do all prototypes correctly.... -CWS */
#ifndef NO_LINT_ARGS
#ifdef __STDC__
static void unsample(inven_type *);
#else
static void unsample();
#endif
#endif
char titles[MAX_TITLES][10];
/* Object descriptor routines */
int
is_a_vowel(ch)
int ch;
{
switch (ch & 127) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
return (TRUE);
default:
return (FALSE);
}
}
/* Initialize all Potions, wands, staves, scrolls, etc. */
void
magic_init()
{
register int h, i, j, k;
register const char *tmp;
vtype string;
set_seed(randes_seed);
/* The first 3 entries for colors are fixed, (slime & apple juice, water) */
for (i = 3; i < MAX_COLORS; i++) {
j = randint(MAX_COLORS - 3) + 2;
tmp = colors[i];
colors[i] = colors[j];
colors[j] = tmp;
}
for (i = 0; i < MAX_WOODS; i++) {
j = randint(MAX_WOODS) - 1;
tmp = woods[i];
woods[i] = woods[j];
woods[j] = tmp;
}
for (i = 0; i < MAX_METALS; i++) {
j = randint(MAX_METALS) - 1;
tmp = metals[i];
metals[i] = metals[j];
metals[j] = tmp;
}
for (i = 0; i < MAX_ROCKS; i++) {
j = randint(MAX_ROCKS) - 1;
tmp = rocks[i];
rocks[i] = rocks[j];
rocks[j] = tmp;
}
for (i = 0; i < MAX_AMULETS; i++) {
j = randint(MAX_AMULETS) - 1;
tmp = amulets[i];
amulets[i] = amulets[j];
amulets[j] = tmp;
}
for (i = 0; i < MAX_MUSH; i++) {
j = randint(MAX_MUSH) - 1;
tmp = mushrooms[i];
mushrooms[i] = mushrooms[j];
mushrooms[j] = tmp;
}
for (h = 0; h < MAX_TITLES; h++) {
string[0] = '\0';
k = randint(2) + 1;
for (i = 0; i < k; i++) {
for (j = randint(2); j > 0; j--)
(void)strcat(string, syllables[randint(MAX_SYLLABLES) - 1]);
if (i < k - 1)
(void)strcat(string, " ");
}
if (string[8] == ' ')
string[8] = '\0';
else
string[9] = '\0';
(void)strcpy(titles[h], string);
}
reset_seed();
}
int16
object_offset(t_ptr)
inven_type *t_ptr;
{
switch (t_ptr->tval) {
case TV_ROD:
return (7); /* -CFT */
case TV_AMULET:
return (0);
case TV_RING:
return (1);
case TV_STAFF:
return (2);
case TV_WAND:
return (3);
case TV_SCROLL1:
case TV_SCROLL2:
return (4);
case TV_POTION1:
case TV_POTION2:
return (5);
case TV_FOOD:
if ((t_ptr->subval & (ITEM_SINGLE_STACK_MIN - 1)) < MAX_MUSH)
return (6);
return (-1);
default:
return (-1);
}
}
/* Remove "Secret" symbol for identity of object */
void
known1(i_ptr)
inven_type *i_ptr;
{
int16 offset;
int8u indexx;
if ((offset = object_offset(i_ptr)) < 0)
return;
offset <<= 6;
indexx = i_ptr->subval & (ITEM_SINGLE_STACK_MIN - 1);
object_ident[offset + indexx] |= OD_KNOWN1;
/* clear the tried flag, since it is now known */
object_ident[offset + indexx] &= ~OD_TRIED;
}
int
known1_p(i_ptr)
inven_type *i_ptr;
{
int16 offset;
int8u indexx;
/* Items which don't have a 'color' are always known1, so that they can be
* carried in order in the inventory.
*/
if ((offset = object_offset(i_ptr)) < 0)
return OD_KNOWN1;
if (store_bought_p(i_ptr))
return OD_KNOWN1;
offset <<= 6;
indexx = i_ptr->subval & (ITEM_SINGLE_STACK_MIN - 1);
return (object_ident[offset + indexx] & OD_KNOWN1);
}
/* Remove "Secret" symbol for identity of plusses */
void
known2(i_ptr)
inven_type *i_ptr;
{
unsample(i_ptr);
i_ptr->ident |= ID_KNOWN2;
}
int
known2_p(i_ptr)
inven_type *i_ptr;
{
return (i_ptr->ident & ID_KNOWN2);
}
void
clear_known2(i_ptr)
inven_type *i_ptr;
{
i_ptr->ident &= ~ID_KNOWN2;
}
void
clear_empty(i_ptr)
inven_type *i_ptr;
{
i_ptr->ident &= ~ID_EMPTY;
}
void
store_bought(i_ptr)
inven_type *i_ptr;
{
i_ptr->ident |= ID_STOREBOUGHT;
known2(i_ptr);
}
int
store_bought_p(i_ptr)
inven_type *i_ptr;
{
return (i_ptr->ident & ID_STOREBOUGHT);
}
/* Remove an automatically generated inscription. -CJS- */
static void
unsample(i_ptr)
inven_type *i_ptr;
{
int16 offset;
int8u indexx;
/* used to clear ID_DAMD flag, but I think it should remain set */
i_ptr->ident &= ~(ID_MAGIK | ID_EMPTY);
if ((offset = object_offset(i_ptr)) < 0)
return;
offset <<= 6;
indexx = i_ptr->subval & (ITEM_SINGLE_STACK_MIN - 1);
object_ident[offset + indexx] &= ~OD_TRIED;
}
/* unquote() is no longer needed */
/* Somethings been sampled -CJS- */
void
sample(i_ptr)
inven_type *i_ptr;
{
int16 offset;
int8u indexx;
if ((offset = object_offset(i_ptr)) < 0)
return;
offset <<= 6;
indexx = i_ptr->subval & (ITEM_SINGLE_STACK_MIN - 1);
object_ident[offset + indexx] |= OD_TRIED;
}
/* Somethings been identified */
/*
* extra complexity by CJS so that it can merge store/dungeon objects when
* appropriate
*/
void
identify(item)
int *item;
{
register int i, x1, x2;
int j;
register inven_type *i_ptr, *t_ptr;
i_ptr = &inventory[*item];
if ((i_ptr->flags & TR_CURSED) && (i_ptr->tval != TV_MAGIC_BOOK) &&
(i_ptr->tval != TV_PRAYER_BOOK))
add_inscribe(i_ptr, ID_DAMD);
if (!known1_p(i_ptr)) {
known1(i_ptr);
x1 = i_ptr->tval;
x2 = i_ptr->subval;
if (x2 < ITEM_SINGLE_STACK_MIN || x2 >= ITEM_GROUP_MIN)
/* no merging possible */
;
else
for (i = 0; i < inven_ctr; i++) {
t_ptr = &inventory[i];
if (t_ptr->tval == x1 && t_ptr->subval == x2 && i != *item
&& ((int)t_ptr->number + (int)i_ptr->number < 256)) {
/* make *item the smaller number */
if (*item > i) {
j = *item;
*item = i;
i = j;
}
msg_print("You combine similar objects from the shop and dungeon.");
inventory[*item].number += inventory[i].number;
inven_ctr--;
for (j = i; j < inven_ctr; j++)
inventory[j] = inventory[j + 1];
invcopy(&inventory[j], OBJ_NOTHING);
}
}
}
}
/*
* If an object has lost magical properties, remove the appropriate portion
* of the name. -CJS-
*/
void
unmagic_name(i_ptr)
inven_type *i_ptr;
{
i_ptr->name2 = SN_NULL;
}
/* defines for p1_use, determine how the p1 field is printed */
#define IGNORED 0 /* never show (+x) */
#define CHARGES 1 /* show p1 as charges */
#define PLUSSES 2 /* show p1 as (+x) only */
#define LIGHT 3 /* show p1 as turns of light */
#define FLAGS 4 /* show p1 as (+x of yyy) */
#define Z_PLUSSES 5 /* always show p1 as (+x), even if x==0 -CWS */
/* Returns a description of item for inventory
* pref indicates that there should be an article added (prefix)
*
* note that since out_val can easily exceed 80 characters, objdes must
* always be called with a bigvtype as the first paramter
*****
* Note that objdes now never returns a description ending with punctuation
* (ie, "."'s) -CWS
*/
void
objdes(out_val, i_ptr, pref)
char *out_val;
register inven_type *i_ptr;
int pref;
{
/* base name, modifier string */
register const char *basenm, *modstr;
bigvtype tmp_val;
vtype tmp_str, damstr;
int indexx, p1_use, modify, append_name;
indexx = i_ptr->subval & (ITEM_SINGLE_STACK_MIN - 1);
basenm = object_list[i_ptr->index].name;
modstr = NULL;
damstr[0] = '\0';
p1_use = IGNORED;
modify = (known1_p(i_ptr) ? FALSE : TRUE);
append_name = FALSE;
switch (i_ptr->tval) {
case TV_MISC:
case TV_CHEST:
break;
case TV_SLING_AMMO:
case TV_BOLT:
case TV_ARROW:
(void)sprintf(damstr, " (%dd%d)", i_ptr->damage[0], i_ptr->damage[1]);
break;
case TV_LIGHT:
p1_use = LIGHT;
if (!stricmp("The Phial of Galadriel", basenm) && !known2_p(i_ptr))
basenm = "a Shining Phial";
if (!stricmp("The Star of Elendil", basenm) && !known2_p(i_ptr))
basenm = "a Shining Gem";
if (!stricmp("The Arkenstone of Thrain", basenm) && !known2_p(i_ptr))
basenm = "a Shining Gem";
break;
case TV_SPIKE:
break;
case TV_BOW:
switch(i_ptr->subval) { /* whole new code -CFT */
case 20: case 1: /* sling, sh. bow */
strcpy(damstr, " (x2)");
break;
case 21: case 2: case 10: /* sling of M, s bow of M, l bow, l xbow */
strcpy(damstr, " (x3)");
break;
case 3: case 11: /* l bow of M, l xbow of M, h xbow, BARD, CUBRAGOL */
strcpy(damstr, " (x4)");
break;
case 4: case 12: /* h xbow of M, BELEG */
strcpy(damstr, " (x5)");
break;
default: /* just in case... */
strcpy(damstr, " (unknown mult.)");
}
if (i_ptr->flags2 & TR_ARTIFACT) /* only show p1 for artifacts... */
p1_use = FLAGS;
break;
case TV_HAFTED:
case TV_POLEARM:
case TV_SWORD:
(void)sprintf(damstr, " (%dd%d)", i_ptr->damage[0], i_ptr->damage[1]);
p1_use = FLAGS;
break;
case TV_DIGGING:
p1_use = Z_PLUSSES;
(void)sprintf(damstr, " (%dd%d)", i_ptr->damage[0], i_ptr->damage[1]);
break;
case TV_BOOTS:
case TV_GLOVES:
case TV_CLOAK:
case TV_HELM:
case TV_SHIELD:
case TV_HARD_ARMOR:
case TV_SOFT_ARMOR:
p1_use = FLAGS;
break;
case TV_AMULET:
p1_use = FLAGS;
if (modify || !(plain_descriptions || store_bought_p(i_ptr))) {
basenm = "& %s Amulet";
modstr = amulets[indexx];
if (!modify)
append_name = TRUE;
} else {
basenm = "& Amulet";
append_name = TRUE;
}
break;
case TV_RING:
if (!stricmp("Power", basenm)) { /* name this "the One Ring" -CWS */
append_name = FALSE;
if (!known2_p(i_ptr))
basenm = "a plain gold Ring";
else
basenm = "The One Ring";
} else if (modify || !(plain_descriptions || store_bought_p(i_ptr))) {
basenm = "& %s Ring";
modstr = rocks[indexx];
if (!modify)
append_name = TRUE;
} else {
basenm = "& Ring";
append_name = TRUE;
}
p1_use = PLUSSES;
break;
case TV_STAFF:
if (modify || !(plain_descriptions || store_bought_p(i_ptr))) {
basenm = "& %s Staff";
modstr = woods[indexx];
if (!modify)
append_name = TRUE;
} else {
basenm = "& Staff";
append_name = TRUE;
}
p1_use = CHARGES;
break;
case TV_WAND:
if (modify || !(plain_descriptions || store_bought_p(i_ptr))) {
basenm = "& %s Wand";
modstr = metals[indexx];
if (!modify)
append_name = TRUE;
} else {
basenm = "& Wand";
append_name = TRUE;
}
p1_use = CHARGES;
break;
case TV_ROD:
if (modify || !(plain_descriptions || store_bought_p(i_ptr))) {
basenm = "& %s Rod";
modstr = metals[indexx];
if (!modify)
append_name = TRUE;
} else {
basenm = "& Rod";
append_name = TRUE;
}
break;
case TV_SCROLL1:
case TV_SCROLL2:
if (modify || !(plain_descriptions || store_bought_p(i_ptr))) {
basenm = "& Scroll~ titled \"%s\"";
modstr = titles[indexx];
if (!modify)
append_name = TRUE;
} else {
basenm = "& Scroll~";
append_name = TRUE;
}
break;
case TV_POTION1:
case TV_POTION2:
if (modify || !(plain_descriptions || store_bought_p(i_ptr))) {
basenm = "& %s Potion~";
modstr = colors[indexx];
if (!modify)
append_name = TRUE;
} else {
basenm = "& Potion~";
append_name = TRUE;
}
break;
case TV_FLASK:
break;
case TV_FOOD:
if (modify || !(plain_descriptions || store_bought_p(i_ptr))) {
if (!modify)
append_name = TRUE;
if (indexx <= 15)
basenm = "& %s Mushroom~";
else if (indexx <= 20)
basenm = "& Hairy %s Mold~";
else
append_name = FALSE; /* Ordinary food has no name appended. */
if (indexx <= 20)
modstr = mushrooms[indexx];
} else {
append_name = TRUE;
if (indexx <= 15)
basenm = "& Mushroom~";
else if (indexx <= 20)
basenm = "& Hairy Mold~";
else
/* Ordinary food does not have a name appended. */
append_name = FALSE;
}
break;
case TV_MAGIC_BOOK:
modstr = basenm;
basenm = "& Book~ of Magic Spells %s";
break;
case TV_PRAYER_BOOK:
modstr = basenm;
basenm = "& Holy Book~ of Prayers %s";
break;
case TV_OPEN_DOOR:
case TV_CLOSED_DOOR:
case TV_SECRET_DOOR:
case TV_RUBBLE:
break;
case TV_GOLD:
case TV_INVIS_TRAP:
case TV_VIS_TRAP:
case TV_UP_STAIR:
case TV_DOWN_STAIR:
(void)strcpy(out_val, object_list[i_ptr->index].name);
/* (void) strcat(out_val, "."); avoid ".." bug -CWS */
return;
case TV_STORE_DOOR:
(void)sprintf(out_val, "the entrance to the %s",
object_list[i_ptr->index].name);
return;
default:
(void)strcpy(out_val, "Error in objdes()");
return;
}
if (modstr != NULL)
(void)sprintf(tmp_val, basenm, modstr);
else
(void)strcpy(tmp_val, basenm);
if (append_name) {
(void)strcat(tmp_val, " of ");
(void)strcat(tmp_val, object_list[i_ptr->index].name);
}
if (i_ptr->number != 1) {
insert_str(tmp_val, "ch~", "ches");
insert_str(tmp_val, "~", "s");
} else
insert_str(tmp_val, "~", NULL);
if (!pref) {
if (!strncmp("some", tmp_val, 4))
(void)strcpy(out_val, &tmp_val[5]);
else if (tmp_val[0] == '&')
/* eliminate the '& ' at the beginning */
(void)strcpy(out_val, &tmp_val[2]);
else
(void)strcpy(out_val, tmp_val);
} else {
if (i_ptr->name2 != SN_NULL && known2_p(i_ptr)) {
(void)strcat(tmp_val, " ");
(void)strcat(tmp_val, special_names[i_ptr->name2]);
}
if (damstr[0] != '\0')
(void)strcat(tmp_val, damstr);
if (known2_p(i_ptr)) {
/* originally used %+d, but several machines don't support it */
if (i_ptr->ident & ID_SHOW_HITDAM)
(void)sprintf(tmp_str, " (%c%d,%c%d)",
(i_ptr->tohit < 0) ? '-' : '+', MY_ABS( i_ptr->tohit),
(i_ptr->todam < 0) ? '-' : '+', MY_ABS(i_ptr->todam));
else if (i_ptr->tohit != 0)
(void)sprintf(tmp_str, " (%c%d)",
(i_ptr->tohit < 0) ? '-' : '+', MY_ABS(i_ptr->tohit));
else if (i_ptr->todam != 0)
(void)sprintf(tmp_str, " (%c%d)",
(i_ptr->todam < 0) ? '-' : '+', MY_ABS(i_ptr->todam));
else
tmp_str[0] = '\0';
(void)strcat(tmp_val, tmp_str);
}
/* Crowns have a zero base AC, so make a special test for them. */
if (i_ptr->ac != 0 || (i_ptr->tval == TV_HELM)) {
(void)sprintf(tmp_str, " [%d", i_ptr->ac);
(void)strcat(tmp_val, tmp_str);
if (known2_p(i_ptr)) {
/* originally used %+d, but several machines don't support it */
(void)sprintf(tmp_str, ",%c%d",
(i_ptr->toac < 0) ? '-' : '+', MY_ABS(i_ptr->toac));
(void)strcat(tmp_val, tmp_str);
}
(void)strcat(tmp_val, "]");
} else if ((i_ptr->toac != 0) && known2_p(i_ptr)) {
/* originally used %+d, but several machines don't support it */
(void)sprintf(tmp_str, " [%c%d]",
(i_ptr->toac < 0) ? '-' : '+', MY_ABS(i_ptr->toac));
(void)strcat(tmp_val, tmp_str);
}
tmp_str[0] = '\0';
/* override defaults, check for p1 flags in the ident field */
if (p1_use != IGNORED) {
if (p1_use == LIGHT);
else if (i_ptr->ident & ID_NOSHOW_P1)
p1_use = IGNORED;
else if (i_ptr->ident & ID_NOSHOW_TYPE)
p1_use = PLUSSES;
}
if (p1_use == IGNORED);
else if ((p1_use == LIGHT) && !(i_ptr->flags2 & TR_ARTIFACT))
(void)sprintf(tmp_str, " with %d turns of light", i_ptr->p1);
else if (known2_p(i_ptr)) {
if (p1_use == CHARGES)
(void)sprintf(tmp_str, " (%d charge%s", i_ptr->p1,
(i_ptr->p1 == 1 ? ")" : "s)"));
else if (p1_use == Z_PLUSSES) /* (+0) digging implements -CWS */
(void)sprintf(tmp_str, " (%c%d)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
else if (i_ptr->p1 != 0) {
if (p1_use == PLUSSES)
(void)sprintf(tmp_str, " (%c%d)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
else if (i_ptr->ident & ID_NOSHOW_TYPE)
(void)sprintf(tmp_str, " (%c%d)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
else if (p1_use == FLAGS) {
if ((i_ptr->flags & TR_SPEED) &&
(i_ptr->name2 != SN_SPEED))
(void)sprintf(tmp_str, " (%c%d to speed)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
else if (i_ptr->flags & TR_SEARCH)
/* && (i_ptr->name2 != SN_SEARCH)) */
(void)sprintf(tmp_str, " (%c%d to searching)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
else if ((i_ptr->flags & TR_STEALTH) &&
(i_ptr->name2 != SN_STEALTH))
(void)sprintf(tmp_str, " (%c%d to stealth)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
else if ((i_ptr->flags & TR_INFRA) &&
(i_ptr->name2 != SN_INFRAVISION))
(void)sprintf(tmp_str, " (%c%d to infravision)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
else if (i_ptr->flags2 & TR_ATTACK_SPD) {
if (MY_ABS(i_ptr->p1) == 1)
(void)sprintf(tmp_str, " (%c%d attack)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
else
(void)sprintf(tmp_str, " (%c%d attacks)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
} /* attack speed */
else
(void)sprintf(tmp_str, " (%c%d)",
(i_ptr->p1 < 0) ? '-' : '+', MY_ABS(i_ptr->p1));
} /* p1_use == FLAGS */
} /* p1 != 0 */
} /* if known2_p (fully identified) */
(void)strcat(tmp_val, tmp_str);
/* ampersand is always the first character */
if (tmp_val[0] == '&') {
/* use &tmp_val[1], so that & does not appear in output */
if (i_ptr->number > 1)
(void)sprintf(out_val, "%d%s", (int)i_ptr->number, &tmp_val[1]);
else if (i_ptr->number < 1)
(void)sprintf(out_val, "%s%s", "no more", &tmp_val[1]);
else if (known2_p(i_ptr) && (i_ptr->tval >= TV_MIN_WEAR)
&& (i_ptr->tval <= TV_MAX_WEAR) &&
(i_ptr->flags2 & TR_ARTIFACT))
(void)sprintf(out_val, "The%s", &tmp_val[1]);
else if (is_a_vowel(tmp_val[2]))
(void)sprintf(out_val, "an%s", &tmp_val[1]);
else
(void)sprintf(out_val, "a%s", &tmp_val[1]);
}
/* handle 'no more' case specially */
else if (i_ptr->number < 1) {
/* check for "some" at start */
if (!strncmp("some", tmp_val, 4))
(void)sprintf(out_val, "no more %s", &tmp_val[5]);
/* here if no article */
else
(void)sprintf(out_val, "no more %s", tmp_val);
} else
(void)strcpy(out_val, tmp_val);
tmp_str[0] = '\0';
if ((indexx = object_offset(i_ptr)) >= 0) {
indexx = (indexx <<= 6) +
(i_ptr->subval & (ITEM_SINGLE_STACK_MIN - 1));
/* don't print tried string for store bought items */
if ((object_ident[indexx] & OD_TRIED) && !store_bought_p(i_ptr))
(void)strcat(tmp_str, "tried ");
}
if ((i_ptr->ident & (ID_MAGIK | ID_EMPTY | ID_DAMD)) &&
i_ptr->tval != TV_MAGIC_BOOK && i_ptr->tval != TV_PRAYER_BOOK) {
if (i_ptr->ident & ID_MAGIK)
(void)strcat(tmp_str, "blessed ");
if (i_ptr->ident & ID_EMPTY)
(void)strcat(tmp_str, "empty ");
if (i_ptr->ident & ID_DAMD)
(void)strcat(tmp_str, "cursed ");
}
if ((known2_p(i_ptr) || store_bought_p(i_ptr)) &&
((!strncmp(i_ptr->inscrip, "average", 7)) ||
(!strncmp(i_ptr->inscrip, "good", 4)) ||
(!strncmp(i_ptr->inscrip, "excellent", 9)) ||
(!strncmp(i_ptr->inscrip, "special", 7))))
i_ptr->inscrip[0] = '\0';
if (i_ptr->inscrip[0] != '\0')
(void)strcat(tmp_str, i_ptr->inscrip);
else if ((indexx = strlen(tmp_str)) > 0)
/* remove the extra blank at the end */
tmp_str[indexx - 1] = '\0';
if (tmp_str[0]) {
(void)sprintf(tmp_val, " {%s}", tmp_str);
(void)strcat(out_val, tmp_val);
}
/* (void) strcat(out_val, "."); avoid ".." bug -CWS */
}
}
void
invcopy(to, from_index)
register inven_type *to;
int from_index;
{
register treasure_type *from;
from = &object_list[from_index];
to->index = from_index;
to->name2 = SN_NULL;
to->inscrip[0] = '\0';
to->flags = from->flags;
to->flags2 = from->flags2;
to->tval = from->tval;
to->tchar = from->tchar;
to->p1 = from->p1;
to->cost = from->cost;
to->subval = from->subval;
to->number = from->number;
to->weight = from->weight;
to->tohit = from->tohit;
to->todam = from->todam;
to->ac = from->ac;
to->toac = from->toac;
to->damage[0] = from->damage[0];
to->damage[1] = from->damage[1];
to->level = from->level;
to->ident = 0;
}
/* Describe number of remaining charges. -RAK- */
void
desc_charges(item_val)
int item_val;
{
register int rem_num;
vtype out_val;
if (known2_p(&inventory[item_val])) {
rem_num = inventory[item_val].p1;
(void)sprintf(out_val, "You have %d charges remaining.", rem_num);
msg_print(out_val);
}
}
/* Describe amount of item remaining. -RAK- */
void
desc_remain(item_val)
int item_val;
{
bigvtype out_val, tmp_str;
register inven_type *i_ptr;
i_ptr = &inventory[item_val];
i_ptr->number--;
objdes(tmp_str, i_ptr, TRUE);
i_ptr->number++;
(void)sprintf(out_val, "You have %s.", tmp_str);
msg_print(out_val);
}